}
if (strstr(xen_caps, "xen-3.0-x86_32p")) {
- if (dsi->pae_kernel == PAEKERN_no) {
+ if (dsi->pae_kernel == PAEKERN_bimodal) {
+ dsi->pae_kernel = PAEKERN_extended_cr3;
+ } else if (dsi->pae_kernel == PAEKERN_no) {
xc_set_error(XC_INVALID_KERNEL,
"Non PAE-kernel on PAE host.");
return 0;
}
- } else if (dsi->pae_kernel != PAEKERN_no) {
- xc_set_error(XC_INVALID_KERNEL,
- "PAE-kernel on non-PAE host.");
- return 0;
+ } else {
+ if (dsi->pae_kernel == PAEKERN_bimodal) {
+ dsi->pae_kernel = PAEKERN_no;
+ } else if (dsi->pae_kernel != PAEKERN_no) {
+ xc_set_error(XC_INVALID_KERNEL,
+ "PAE-kernel on non-PAE host.");
+ return 0;
+ }
}
return 1;
return -EINVAL;
}
- /* Find the section-header strings table. */
- if ( ehdr->e_shstrndx == SHN_UNDEF )
- {
- xc_set_error(XC_INVALID_KERNEL,
- "ELF image has no section-header strings table (shstrtab).");
- return -EINVAL;
- }
- shdr = (Elf_Shdr *)(image + ehdr->e_shoff +
- (ehdr->e_shstrndx*ehdr->e_shentsize));
- shstrtab = image + shdr->sh_offset;
-
dsi->__elfnote_section = NULL;
dsi->__xen_guest_string = NULL;
/* Fall back to looking for the special '__xen_guest' section. */
if ( dsi->__elfnote_section == NULL )
{
+ /* Find the section-header strings table. */
+ if ( ehdr->e_shstrndx == SHN_UNDEF )
+ {
+ xc_set_error(XC_INVALID_KERNEL,
+ "ELF image has no section-header strings table.");
+ return -EINVAL;
+ }
+ shdr = (Elf_Shdr *)(image + ehdr->e_shoff +
+ (ehdr->e_shstrndx*ehdr->e_shentsize));
+ shstrtab = image + shdr->sh_offset;
+
for ( h = 0; h < ehdr->e_shnum; h++ )
{
shdr = (Elf_Shdr *)(image + ehdr->e_shoff + (h*ehdr->e_shentsize));
}
/*
+ * A "bimodal" ELF note indicates the kernel will adjust to the
+ * current paging mode, including handling extended cr3 syntax.
* If we have ELF notes then PAE=yes implies that we must support
* the extended cr3 syntax. Otherwise we need to find the
* [extended-cr3] syntax in the __xen_guest string.
if ( dsi->__elfnote_section )
{
p = xen_elfnote_string(dsi, XEN_ELFNOTE_PAE_MODE);
- if ( p != NULL && strncmp(p, "yes", 3) == 0 )
+ if ( p != NULL && strncmp(p, "bimodal", 7) == 0 )
+ dsi->pae_kernel = PAEKERN_bimodal;
+ else if ( p != NULL && strncmp(p, "yes", 3) == 0 )
dsi->pae_kernel = PAEKERN_extended_cr3;
}
#define PAEKERN_no 0
#define PAEKERN_yes 1
#define PAEKERN_extended_cr3 2
+#define PAEKERN_bimodal 3
unsigned int pae_kernel;
unsigned int load_symtab;
if ( (rc = parseelfimage(&dsi)) != 0 )
return rc;
- dom0_pae = (dsi.pae_kernel != PAEKERN_no);
xen_pae = (CONFIG_PAGING_LEVELS == 3);
+ if (dsi.pae_kernel == PAEKERN_bimodal)
+ dom0_pae = xen_pae;
+ else
+ dom0_pae = (dsi.pae_kernel != PAEKERN_no);
if ( dom0_pae != xen_pae )
{
printk("PAE mode mismatch between Xen and DOM0 (xen=%s, dom0=%s)\n",
return -EINVAL;
}
- if ( xen_pae && dsi.pae_kernel == PAEKERN_extended_cr3 )
+ if ( xen_pae && (dsi.pae_kernel == PAEKERN_extended_cr3 ||
+ dsi.pae_kernel == PAEKERN_bimodal) )
set_bit(VMASST_TYPE_pae_extended_cr3, &d->vm_assist);
if ( (p = xen_elfnote_string(&dsi, XEN_ELFNOTE_FEATURES)) != NULL )
return -EINVAL;
}
- /* Find the section-header strings table. */
- if ( ehdr->e_shstrndx == SHN_UNDEF )
- {
- printk("ELF image has no section-header strings table (shstrtab).\n");
- return -EINVAL;
- }
- shdr = (Elf_Shdr *)(image + ehdr->e_shoff +
- (ehdr->e_shstrndx*ehdr->e_shentsize));
- shstrtab = image + shdr->sh_offset;
-
dsi->__elfnote_section = NULL;
dsi->__xen_guest_string = NULL;
/* Fall back to looking for the special '__xen_guest' section. */
if ( dsi->__elfnote_section == NULL )
{
+ /* Find the section-header strings table. */
+ if ( ehdr->e_shstrndx == SHN_UNDEF )
+ {
+ printk("ELF image has no section-header strings table.\n");
+ return -EINVAL;
+ }
+ shdr = (Elf_Shdr *)(image + ehdr->e_shoff +
+ (ehdr->e_shstrndx*ehdr->e_shentsize));
+ shstrtab = image + shdr->sh_offset;
+
for ( h = 0; h < ehdr->e_shnum; h++ )
{
shdr = (Elf_Shdr *)(image + ehdr->e_shoff + (h*ehdr->e_shentsize));
}
/*
+ * A "bimodal" ELF note indicates the kernel will adjust to the
+ * current paging mode, including handling extended cr3 syntax.
* If we have ELF notes then PAE=yes implies that we must support
* the extended cr3 syntax. Otherwise we need to find the
* [extended-cr3] syntax in the __xen_guest string.
if ( dsi->__elfnote_section )
{
p = xen_elfnote_string(dsi, XEN_ELFNOTE_PAE_MODE);
- if ( p != NULL && strncmp(p, "yes", 3) == 0 )
+ if ( p != NULL && strncmp(p, "bimodal", 7) == 0 )
+ dsi->pae_kernel = PAEKERN_bimodal;
+ else if ( p != NULL && strncmp(p, "yes", 3) == 0 )
dsi->pae_kernel = PAEKERN_extended_cr3;
-
}
else
{
#define PAEKERN_no 0
#define PAEKERN_yes 1
#define PAEKERN_extended_cr3 2
+#define PAEKERN_bimodal 3
unsigned int pae_kernel;
/* Initialised by loader: Private. */
unsigned long elf_paddr_offset;